package interfaces.subpanel.clustering.gui;

import interfaces.mainpanel.gui.TesisMainGUI;
import interfaces.subpanel.classifier.ResultCellRenderer;
import interfaces.subpanel.classifier.ResultClassifyEvaluation;
import interfaces.subpanel.preprocesamiento.gui.ClusteredScenariesTable;
import interfaces.subpanel.preprocesamiento.gui.StopWordsPanelGUI;
import interfaces.subpanel.summaryinfo.gui.ResultSummaryEvaluation;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableColumnModel;

import model.ClusteredGenericScenarie;
import model.GenericScenarie;
import model.SummaryGenericScenarie;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;

import renderers.LabelRenderer;
import renderers.TextAreaRenderer;
import utils.ImagenesUtils;
import weka.clusterers.ClusterEvaluation;
import weka.clusterers.Clusterer;
import weka.clusterers.EM;
import weka.clusterers.FilteredClusterer;
import weka.clusterers.XMeans;
import weka.core.Instance;
import weka.core.Instances;
import weka.filters.Filter;
import weka.filters.unsupervised.attribute.Remove;
import weka.gui.beans.ShadowBorder;

import comparators.ProjectIdComparator;

import enumerations.AttributesEnum;

public class ClusteringGUI extends JPanel implements ActionListener, ListSelectionListener {

	private static final String TIME_PATTERN = "hh:mm:ss";

	private static final int ATTRIBUTE_COLUMN_WIDTH = 50;

	private static final String PROMPT_COMBO = "Select";

	private static final long serialVersionUID = 1L;

	private static final String INIT_NUM_FOLDS = "3";

	private TesisMainGUI mainGUI;

	private JTextField numClusters, minClustersField, maxClustersField, emClusters;

	private JComboBox projectList, clusterList;

	private List<String> projectsStrings = new ArrayList<String>();

	private String[] clusterStrings = { " XMeans ", " EM " };

	private JButton filterDataButton, proccessButton, clearDataButton;

	private JList listResults, listResultsClustered;

	private DefaultListModel listResultsModel, listResultsClusteredModel;

	private JList listScenaries;

	private JPanel emClustersPanel;

	private DefaultListModel listScenariesModel;

	private ClusteredScenariesTable clusteredScenariesTable;

	private JTable table;

	private JTextArea resultDetailsArea;

	private ProjectIdComparator comparator = new ProjectIdComparator();

	private StopWordsPanelGUI stopWordsPanelGUI;

	/****************************************************************************/
	/** The following three properties store the selected configuration. **/
	/****************************************************************************/
	private String projectIdSelected;

	private ResultClassifyEvaluation evaluationSelected;

	private Instances filteredInstancesSelected;

	/****************************************************************************/

	public ClusteringGUI(TesisMainGUI mainGUI) {

		super(new BorderLayout(5, 5));

		this.mainGUI = mainGUI;

		this.proccessButton = new JButton("Start", ImagenesUtils.createImageIcon(this.getClass(), "/processing25.png"));
		this.proccessButton.addActionListener(this);
		this.clearDataButton = new JButton("Clear Data", ImagenesUtils.createImageIcon(this.getClass(), "/dropBox25.png"));
		this.clearDataButton.addActionListener(this);
		this.filterDataButton = new JButton("Filter Data", ImagenesUtils.createImageIcon(this.getClass(), "/filter25.png"));
		this.filterDataButton.addActionListener(this);
		JPanel buttonsPanel = new JPanel(new GridLayout(1, 3, 5, 5));
		buttonsPanel.add(this.filterDataButton);
		buttonsPanel.add(this.clearDataButton);
		buttonsPanel.add(this.proccessButton);

		JPanel projectPanel = new JPanel(new BorderLayout(8, 2));
		this.projectsStrings.add(PROMPT_COMBO);
		this.projectList = new JComboBox(this.projectsStrings.toArray());
		this.projectList.setSelectedIndex(0);
		this.projectList.addActionListener(this);
		JLabel projectLabel = new JLabel("Project:", JLabel.LEFT);
		projectPanel.add(projectLabel, BorderLayout.WEST);
		projectPanel.add(this.projectList);

		JPanel clusterPanel = new JPanel(new BorderLayout(8, 2));
		this.clusterList = new JComboBox(this.clusterStrings);
		this.clusterList.setSelectedIndex(0);
		this.clusterList.addActionListener(this);
		JLabel clusterLabel = new JLabel("Clusterer:", JLabel.LEFT);
		clusterPanel.add(clusterLabel, BorderLayout.WEST);
		clusterPanel.add(this.clusterList);

		JPanel minClusterPanel = new JPanel(new BorderLayout(8, 2));
		this.minClustersField = new JTextField();
		this.minClustersField.setColumns(3);
		this.minClustersField.setText("2");
		JLabel minClusterLabel = new JLabel("Min.:", JLabel.LEFT);
		minClusterPanel.add(minClusterLabel, BorderLayout.WEST);
		minClusterPanel.add(this.minClustersField);

		JPanel maxClusterPanel = new JPanel(new BorderLayout(8, 2));
		this.maxClustersField = new JTextField();
		this.maxClustersField.setColumns(3);
		this.maxClustersField.setText("5");
		JLabel maxClusterLabel = new JLabel("Max.:", JLabel.LEFT);
		maxClusterPanel.add(maxClusterLabel, BorderLayout.WEST);
		maxClusterPanel.add(this.maxClustersField);

		this.emClustersPanel = new JPanel(new BorderLayout(8, 2));
		this.emClusters = new JTextField();
		this.emClusters.setColumns(3);
		this.emClusters.setText("-1");
		JLabel emClustersLabel = new JLabel("Num.:", JLabel.LEFT);
		this.emClustersPanel.add(emClustersLabel, BorderLayout.WEST);
		this.emClustersPanel.add(this.emClusters);
		this.emClusters.setEnabled(false);

		JPanel clustersPanel = new JPanel(new GridLayout(1, 3));
		clustersPanel.add(minClusterPanel);
		clustersPanel.add(maxClusterPanel);
		clustersPanel.add(this.emClustersPanel);

		JPanel configurationPanel = new JPanel(new GridLayout(1, 2));
		configurationPanel.add(projectPanel);
		configurationPanel.add(clusterPanel);

		JPanel selectionPanel = new JPanel(new GridLayout(3, 1, 5, 5));
		selectionPanel
				.setBorder(BorderFactory.createCompoundBorder(
						BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Clustering Configuration: "),
								BorderFactory.createEmptyBorder(5, 5, 5, 5)), selectionPanel.getBorder()));
		selectionPanel.add(configurationPanel);
		selectionPanel.add(clustersPanel);
		selectionPanel.add(buttonsPanel);

		this.listResultsModel = new DefaultListModel();
		this.listResults = new JList(this.listResultsModel);
		this.listResults.setCellRenderer(new ResultCellRenderer(ImagenesUtils.createImageIcon(this.getClass(), "/check.png")));
		this.listResults.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		this.listResults.setSelectedIndex(0);
		this.listResults.addListSelectionListener(this);

		JScrollPane resultsPane = new JScrollPane(this.listResults);
		resultsPane.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Classified Results: "), BorderFactory.createEmptyBorder(5, 5, 5, 5)),
				resultsPane.getBorder()));

		this.listResultsClusteredModel = new DefaultListModel();
		this.listResultsClustered = new JList(this.listResultsClusteredModel);
		this.listResultsClustered.setCellRenderer(new ResultClusteredCellRenderer(ImagenesUtils.createImageIcon(this.getClass(), "/check.png")));
		this.listResultsClustered.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		this.listResultsClustered.setSelectedIndex(0);
		this.listResultsClustered.addListSelectionListener(this);

		JScrollPane resultsPaneClustered = new JScrollPane(this.listResultsClustered);
		resultsPaneClustered.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Clustering Results: "), BorderFactory.createEmptyBorder(5, 5, 5, 5)),
				resultsPaneClustered.getBorder()));

		JPanel leftPanel = new JPanel(new GridLayout(3, 1));
		leftPanel.add(selectionPanel);
		leftPanel.add(resultsPane);
		leftPanel.add(resultsPaneClustered);

		this.resultDetailsArea = new JTextArea();
		this.resultDetailsArea.setBorder(new ShadowBorder(2, Color.LIGHT_GRAY));
		this.resultDetailsArea.setLineWrap(false);
		this.resultDetailsArea.setWrapStyleWord(false);
		this.resultDetailsArea.setEditable(false);
		this.resultDetailsArea.setMargin(new Insets(3, 3, 3, 3));

		JScrollPane panelDetailsArea = new JScrollPane(this.resultDetailsArea);

		panelDetailsArea.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createTitledBorder("Clustering Project Result: "), BorderFactory.createEmptyBorder(5, 5, 5, 5)), panelDetailsArea.getBorder()));

		this.clusteredScenariesTable = new ClusteredScenariesTable();
		this.table = new JTable(this.clusteredScenariesTable);
		this.table.setFillsViewportHeight(true);
		this.table.setPreferredScrollableViewportSize(new Dimension(500, 70));
		this.table.getTableHeader().setPreferredSize(new Dimension(10, 27));
		this.table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

		TableColumnModel cmodel = this.table.getColumnModel();
		cmodel.getColumn(0).setCellRenderer(new TextAreaRenderer());
		cmodel.getColumn(1).setCellRenderer(new LabelRenderer());
		JScrollPane scrollPane = new JScrollPane(this.table);
		initColumnSizes();
		scrollPane.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Clustered Scenaries: "), BorderFactory.createEmptyBorder(5, 5, 5, 5)),
				scrollPane.getBorder()));

		JPanel resultDetailPanel = new JPanel(new GridLayout(2, 1));
		resultDetailPanel.add(panelDetailsArea);
		resultDetailPanel.add(scrollPane);

		this.listScenariesModel = new DefaultListModel();
		this.listScenaries = new JList(this.listScenariesModel);
		this.listScenaries.setCellRenderer(new ScenarieCellRenderer(ImagenesUtils.createImageIcon(this.getClass(), "/minus.png")));
		this.listScenaries.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		this.listScenaries.setSelectedIndex(0);
		this.listScenaries.addListSelectionListener(this);

		JScrollPane scenariesPane = new JScrollPane(this.listScenaries);
		scenariesPane.setBorder(BorderFactory.createCompoundBorder(
				BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Clustering Scenaries: "), BorderFactory.createEmptyBorder(5, 5, 5, 5)),
				scenariesPane.getBorder()));

		this.stopWordsPanelGUI = new StopWordsPanelGUI(false, false);

		this.add(leftPanel, BorderLayout.WEST);
		this.add(resultDetailPanel, BorderLayout.CENTER);
		this.add(scenariesPane, BorderLayout.SOUTH);
		this.add(stopWordsPanelGUI, BorderLayout.EAST);
	}

	@Override
	public void actionPerformed(ActionEvent e) {

		if (e.getSource() == this.clearDataButton) {
			this.clearData();
		} else if (e.getSource() == this.filterDataButton) {
			this.selectFilteredFunctionalScenaries();
		} else if (e.getSource() == this.proccessButton) {
			this.clustererInstances();
		} else if (e.getSource() == this.clusterList) {
			if (this.clusterList.getSelectedIndex() == 0) {
				this.minClustersField.setEnabled(true);
				this.maxClustersField.setEnabled(true);
				this.emClusters.setEnabled(false);
			} else {
				this.minClustersField.setEnabled(false);
				this.maxClustersField.setEnabled(false);
				this.emClusters.setEnabled(true);
			}
		}
	}

	private void selectFilteredFunctionalScenaries() {
		if (this.projectList.getSelectedIndex() == 0 || this.listResults.getSelectedIndex() == -1) {
			JOptionPane.showMessageDialog(this, "You must select a project and a result classified item to filter the scenaries to be clustered!",
					"Selection Info!", JOptionPane.INFORMATION_MESSAGE, null);
		} else {
			this.clusteredScenariesTable.removeAllGenericScenaries();
			this.resultDetailsArea.setText("");
			if (this.listScenariesModel != null)
				this.listScenariesModel.clear();
			this.projectIdSelected = (String) this.projectList.getSelectedItem();
			this.evaluationSelected = (ResultClassifyEvaluation) this.listResults.getSelectedValue();

			this.filteredInstancesSelected = new Instances(this.evaluationSelected.getFunctionalInstances());
			List<Instance> instancesToBeRemoved = new ArrayList<Instance>();
			Iterator<Instance> iterator = this.filteredInstancesSelected.iterator();
			while (iterator.hasNext()) {
				Instance instance = iterator.next();
				if (!this.mainGUI.getLoadDataSetGUI().getScenariesById().get(String.valueOf((int) instance.value(1))).getProjectId()
						.equals(this.projectIdSelected)) {
					instancesToBeRemoved.add(instance);
				} else {
					this.listScenariesModel.addElement(this.mainGUI.getLoadDataSetGUI().getScenariesById().get(String.valueOf((int) instance.value(1)))
							.getScenarie());
				}
			}
			this.filteredInstancesSelected.removeAll(instancesToBeRemoved);
			if (CollectionUtils.isEmpty(this.filteredInstancesSelected)) {
				JOptionPane.showMessageDialog(this, "The selected result item doesn't have any Scenarie corresponding to the selected project!",
						"Selection Info!", JOptionPane.INFORMATION_MESSAGE, null);
			}
		}
	}

	private void clustererInstances() {

		if (this.clusterList.getSelectedIndex() == 0) {
			try {
				int min = Integer.parseInt(this.minClustersField.getText());
				int max = Integer.parseInt(this.maxClustersField.getText());
				if (min > max) {
					JOptionPane.showMessageDialog(null, "Min. number clusters must be greater than max. number of clusters!", "Cluster Configuration Error!",
							JOptionPane.ERROR_MESSAGE, ImagenesUtils.createImageIcon(this.getClass(), "/stop.png"));
				}
			} catch (NumberFormatException ex) {
				JOptionPane.showMessageDialog(null, "Check Clusters configuration. That's not a valid number!", "Number Error!", JOptionPane.ERROR_MESSAGE,
						ImagenesUtils.createImageIcon(this.getClass(), "/stop.png"));
			}
		} else {
			try {
				Integer.parseInt(this.emClusters.getText());
			} catch (NumberFormatException ex) {
				JOptionPane.showMessageDialog(null, "Check Clusters configuration. That's not a valid number!", "Number Error!", JOptionPane.ERROR_MESSAGE,
						ImagenesUtils.createImageIcon(this.getClass(), "/stop.png"));
			}
		}

		try {
			if (CollectionUtils.isNotEmpty(this.filteredInstancesSelected)) {

				if (this.mainGUI.getLoadDataSetGUI().isCrossValidation() && !this.mainGUI.getLoadDataSetGUI().validateFolds())
					return;

				long timeIn = System.currentTimeMillis();

				Remove filter = new Remove();
				filter.setAttributeIndices("" + (this.filteredInstancesSelected.classIndex() + 1));
				filter.setInputFormat(this.filteredInstancesSelected);
				Instances dataClusterer = Filter.useFilter(this.filteredInstancesSelected, filter);

				Clusterer clusterer = null;
				if (this.clusterList.getSelectedIndex() == 0) {

					clusterer = new XMeans();
					((XMeans) clusterer).setSeed(5);
					((XMeans) clusterer).setMaxIterations(10);
					((XMeans) clusterer).setMaxKMeans(10);
					((XMeans) clusterer).setMaxKMeansForChildren(10);
					((XMeans) clusterer).setMaxNumClusters(Integer.valueOf(this.maxClustersField.getText()));
					((XMeans) clusterer).setMinNumClusters(Integer.valueOf(this.minClustersField.getText()));

				} else if (this.clusterList.getSelectedIndex() == 1) {

					clusterer = new EM();
					((EM) clusterer).setSeed(5);
					((EM) clusterer).setMaxIterations(10);
					((EM) clusterer).setNumClusters(Integer.parseInt(this.emClusters.getText()));// Cross-Validation

				}

				FilteredClusterer fc = new FilteredClusterer(); // filtered clusterer to ignore attributes
				String[] options = new String[2];
				options[0] = "-R"; // "range"
				IgnoredAttributes ignoredAttributes = getIndexesFromRemoveWords(dataClusterer);
				options[1] = ignoredAttributes.getIgnoredExpression();// we want to ignore the attributes that are in the positions xyz
				Remove remove = new Remove(); // new instance of filter
				remove.setOptions(options); // set options
				remove.setInputFormat(dataClusterer); // inform filter about dataset
				fc.setFilter(remove); // add filter to remove attributes
				fc.setClusterer(clusterer); // bind FilteredClusterer to original clusterer
				fc.buildClusterer(dataClusterer);
				completeDataClustered(fc, dataClusterer, this.clusterList.getSelectedIndex() == 0 ? "XMeans" : "EM", ignoredAttributes.getIgnoredAttributes(),
						timeIn);

			} else
				JOptionPane.showMessageDialog(this, "You must filter funtional scenaries to be classified!", "Empty Functional Scenaries!",
						JOptionPane.ERROR_MESSAGE, ImagenesUtils.createImageIcon(this.getClass(), "/stop.png"));
		} catch (Exception e) {
			JOptionPane.showMessageDialog(this, e.getMessage(), "ERROR!", JOptionPane.ERROR_MESSAGE,
					ImagenesUtils.createImageIcon(this.getClass(), "/stop.png"));
		}
	}

	private IgnoredAttributes getIndexesFromRemoveWords(Instances dataClusterer) {
		String words = this.stopWordsPanelGUI.getStopWordsArea().getText();
		String[] splittedWords = words.split("\n");
		StringBuilder indexesBuilder = new StringBuilder();
		if (!this.stopWordsPanelGUI.getStopWordsArea().getText().equals(""))
			indexesBuilder.append("2-96,");

		if (splittedWords.length != 0) {
			for (String word : splittedWords) {
				String stemWord = this.mainGUI.getPreprocessingGUI().getSelectedStemmer().stem(word);
				int indexWord = dataClusterer.attribute(word) != null ? dataClusterer.attribute(word).index() + 1 : -1;
				int indexStemWord = dataClusterer.attribute(stemWord) != null ? dataClusterer.attribute(stemWord).index() + 1 : -1;
				if (indexWord != -1)
					indexesBuilder.append(indexWord + ",");
				if (indexStemWord != -1 && indexStemWord != indexWord)
					indexesBuilder.append(indexStemWord + ",");
			}
		}

		String indexes = indexesBuilder.toString();
		if (indexes.endsWith(","))
			indexes = indexes.substring(0, indexes.length() - 1);

		if (splittedWords.length == 1 && splittedWords[0].equals(""))
			return new IgnoredAttributes(indexes, 0);
		else
			return new IgnoredAttributes(indexes, splittedWords.length);
	}

	private void completeDataClustered(Clusterer clusterer, Instances dataClusterer, String clustererName, int ignoredAttributes, long timeIn) throws Exception {

		ClusterEvaluation test = new ClusterEvaluation();
		test.setClusterer(clusterer);
		test.evaluateClusterer(this.filteredInstancesSelected);
		long timeOut = System.currentTimeMillis();
		String resultDetail = test.clusterResultsToString();
		String dataset = "DataSet: Software Requirements\n";
		String numberOfInstances = "Number of Instances: " + String.valueOf(this.filteredInstancesSelected.numInstances()) + "\n";
		String numberOfAttributes = "Number of Attributes: " + String.valueOf(this.filteredInstancesSelected.numAttributes() - 94) + "\n";
		String ignoreAttributes = "Ignored Attributes: " + String.valueOf(ignoredAttributes) + "\n";
		String totalTime = "Total Time: " + String.valueOf(timeOut - timeIn) + "\n\n";
		if (clustererName.equals("EM")) {
			String title = " ======= Clustering Summary ======= \n\nClusterer: EM\n";
			String clusteredInstances = test.clusterResultsToString().substring(test.clusterResultsToString().indexOf("Clustered Instances"),
					test.clusterResultsToString().indexOf("Class attribute") - 1);
			resultDetail = title + dataset + numberOfInstances + numberOfAttributes + ignoreAttributes + totalTime + clusteredInstances;
		} else if (clustererName.equals("XMeans")) {
			String title = " ======= Clustering Summary ======= \n\nClusterer: XMeans\n";
			String clusteredInstances = test.clusterResultsToString().substring(test.clusterResultsToString().indexOf("Clustered Instances"),
					test.clusterResultsToString().indexOf("Class attribute") - 1);
			resultDetail = title + dataset + numberOfInstances + numberOfAttributes + ignoreAttributes + totalTime + clusteredInstances;
		}

		this.resultDetailsArea.setText(resultDetail);
		this.resultDetailsArea.setCaretPosition(0);

		List<ClusteredGenericScenarie> listClusteredGenericScenaries = new ArrayList<ClusteredGenericScenarie>();
		for (Instance instance : dataClusterer) {
			int cluster = clusterer.clusterInstance(instance);
			ClusteredGenericScenarie genericScenarie = new ClusteredGenericScenarie(cluster, this.mainGUI.getLoadDataSetGUI().getScenariesById()
					.get(String.valueOf((int) instance.value(0))).getScenarie());
			listClusteredGenericScenaries.add(genericScenarie);
		}
		String title = this.clusterList.getSelectedItem().toString() + "(" + new DateTime().toString(TIME_PATTERN) + ")";

		ResultClusteredEvaluation clusteredEvaluation = new ResultClusteredEvaluation((ResultClassifyEvaluation) this.listResults.getSelectedValue(), title,
				resultDetail, listClusteredGenericScenaries);
		this.listResultsClusteredModel.addElement(clusteredEvaluation);
		this.listResultsClustered.setSelectedIndex(this.listResultsClusteredModel.size() - 1);

		// Agrego los escenarios funcionales resultantes.
		List<SummaryGenericScenarie> functionalScenaries = new ArrayList<SummaryGenericScenarie>();
		for (ClusteredGenericScenarie clusteredGenericScenarie : listClusteredGenericScenaries) {
			functionalScenaries.add(new SummaryGenericScenarie(clusteredGenericScenarie.getCluster(), clusteredGenericScenarie.getScenarie(),
					AttributesEnum.FUNCTIONALITY.name()));
		}

		ResultSummaryEvaluation resultSummaryEvaluation = new ResultSummaryEvaluation(title,
				((ResultClassifyEvaluation) this.listResults.getSelectedValue()).getResultEval(), resultDetail, retrieveQualityScenariesForSummary(),
				functionalScenaries);
		this.mainGUI.getSummaryInfoGUI().addNewResultSummaryEvaluation(resultSummaryEvaluation);

	}

	private List<SummaryGenericScenarie> retrieveQualityScenariesForSummary() {

		List<SummaryGenericScenarie> qualityGenericScenaries = new ArrayList<SummaryGenericScenarie>();

		Instances filteredQualityInstances = new Instances(this.evaluationSelected.getQualityInstances());
		List<Instance> instancesToBeRemoved = new ArrayList<Instance>();
		Iterator<Instance> iterator = filteredQualityInstances.iterator();
		while (iterator.hasNext()) {
			Instance instance = iterator.next();
			if (!this.mainGUI.getLoadDataSetGUI().getScenariesById().get(String.valueOf((int) instance.value(1))).getProjectId().equals(this.projectIdSelected)) {
				instancesToBeRemoved.add(instance);
			}
		}
		filteredQualityInstances.removeAll(instancesToBeRemoved);
		// FIXME filteredQualityInstances me trae las que fueron clasificadas como funcionales tbn.
		for (Instance instance : filteredQualityInstances) {
			qualityGenericScenaries.add(new SummaryGenericScenarie(-1, this.mainGUI.getLoadDataSetGUI().getScenariesById()
					.get(String.valueOf((int) instance.value(1))).getScenarie(), instance.classAttribute().value((int) instance.classValue())));
		}

		return qualityGenericScenaries;
	}

	private void clearData() {
		this.projectList.setSelectedIndex(0);
		this.clusterList.setSelectedIndex(0);
		this.resultDetailsArea.setText(StringUtils.EMPTY);
		if (this.listScenariesModel != null)
			this.listScenariesModel.clear();
		this.listResultsClusteredModel.removeAllElements();
		this.clusteredScenariesTable.removeAllGenericScenaries();
		this.minClustersField.setText("2");
		this.maxClustersField.setText("5");
		this.emClusters.setText("-1");
		this.emClusters.setEnabled(false);
	}

	public void resetData() {
		this.clearData();
		if (this.listResultsModel != null)
			this.listResultsModel.clear();
	}

	private void resetNumFoldsInputText() {
		this.numClusters.setText(INIT_NUM_FOLDS);
	}

	public boolean validateNumFolds() {
		try {
			int clusters = Integer.parseInt(this.numClusters.getText());
			if (clusters < 2 || clusters > 9) {
				JOptionPane.showMessageDialog(null, "Please enter number bigger than 1 and lower than 10!", "Clusters Number Error!",
						JOptionPane.ERROR_MESSAGE, ImagenesUtils.createImageIcon(this.getClass(), "/stop.png"));
				resetNumFoldsInputText();
				numClusters.grabFocus();
				return false;
			}
			return true;
		} catch (NumberFormatException ex) {
			JOptionPane.showMessageDialog(null, "Check clusters number. That's not a valid number!", "Number Error!", JOptionPane.ERROR_MESSAGE,
					ImagenesUtils.createImageIcon(this.getClass(), "/stop.png"));
			resetNumFoldsInputText();
			numClusters.grabFocus();
			return false;
		}
	}

	public String getNumClusters() {
		return this.numClusters.getText();
	}

	public void valueChanged(ListSelectionEvent e) {
		if (e.getValueIsAdjusting() == false && this.listResultsClustered.getSelectedIndex() != -1) {
			ResultClusteredEvaluation resultEval = (ResultClusteredEvaluation) this.listResultsClustered.getSelectedValue();
			this.resultDetailsArea.setText(resultEval.getResultEval());
			this.resultDetailsArea.setCaretPosition(0);
			this.clusteredScenariesTable.removeAllGenericScenaries();
			this.clusteredScenariesTable.addAllGenericScenaries(resultEval.getClusteredGenericScenaries());
		} else if (e.getValueIsAdjusting() == false && this.listResults.getSelectedIndex() == -1) {
			this.listResultsClusteredModel.removeAllElements();
			this.resultDetailsArea.setText(StringUtils.EMPTY);
		}
	}

	public void addNewProjectsIds(List<GenericScenarie> scenaries) {
		this.resetData();
		this.projectsStrings.clear();
		if (CollectionUtils.isNotEmpty(scenaries)) {
			for (GenericScenarie scenarie : scenaries) {
				if (!this.projectsStrings.contains(scenarie.getProjectId()))
					this.projectsStrings.add(scenarie.getProjectId());
			}
		}
		Collections.sort(this.projectsStrings, this.comparator);
		this.projectsStrings.add(0, PROMPT_COMBO);
		this.projectList.setModel(new DefaultComboBoxModel(this.projectsStrings.toArray()));
	}

	public void addElementToResultList(ResultClassifyEvaluation evaluation) {
		this.listResultsModel.addElement(evaluation);
	}

	private void initColumnSizes() {

		this.table.getColumnModel().getColumn(1).setMinWidth(ATTRIBUTE_COLUMN_WIDTH);
		this.table.getColumnModel().getColumn(1).setMaxWidth(ATTRIBUTE_COLUMN_WIDTH);
	}

	private class IgnoredAttributes {

		private String ignoredExpression;
		private int ignoredAttributes;

		public IgnoredAttributes(String ignoredExpression, int ignoredAttributes) {
			super();
			this.ignoredExpression = ignoredExpression;
			this.ignoredAttributes = ignoredAttributes;
		}

		public String getIgnoredExpression() {
			return ignoredExpression;
		}

		public int getIgnoredAttributes() {
			return ignoredAttributes;
		}

	}

}
